package com.anji.sp.push.service.impl;

import com.anji.sp.model.ResponseModel;
import com.anji.sp.push.model.MessageModel;
import com.anji.sp.push.model.po.PushConfiguresPO;
import com.anji.sp.push.model.po.PushUserPO;
import com.anji.sp.push.model.vo.PushUserVO;
import com.anji.sp.push.model.vo.RequestSendBean;
import com.anji.sp.push.service.PushHistoryService;
import com.anji.sp.push.service.PushService;
import com.anji.sp.push.service.PushUserService;
import com.anji.sp.util.APPVersionCheckUtil;
import com.anji.sp.util.StringUtils;
import com.oppo.push.server.Notification;
import com.oppo.push.server.Result;
import com.oppo.push.server.Sender;
import com.oppo.push.server.Target;
import lombok.extern.slf4j.Slf4j;
import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;


/**
 * <p>
 * oppo推送
 * </p>
 *
 * @author kean
 * @since 2021-01-20
 */
@Service
@Slf4j
public class OppoPushServiceImpl implements PushService {

    @Autowired
    private PushHistoryService pushHistoryService;
    @Autowired
    private JPushServiceImpl jPushService;
    @Autowired
    private PushUserService pushUserService;
    @Override
    public ResponseModel pushBatchMessage(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO, String msgId, String targetType) throws Exception {
        if (StringUtils.isEmpty(pushConfiguresPO.getOpAppKey())
                || StringUtils.isEmpty(pushConfiguresPO.getOpMasterSecret())
                || StringUtils.isEmpty(pushConfiguresPO.getAppKey())) {
            //如果参数不全 那么走极光
            jPushService.pushAndroid(requestSendBean,pushConfiguresPO,msgId,"6",false);
            return ResponseModel.errorMsg("参数配置不全");
        }
        MessageModel messageModel;
        try {
            messageModel = pushSignMessage(requestSendBean, pushConfiguresPO);
        } catch (Exception e) {
            //发送失败重新尝试一次
            messageModel = pushSignMessage(requestSendBean, pushConfiguresPO);
        }
        if (messageModel.isSuccess()) {
            pushHistoryService.savePushHistory(requestSendBean, messageModel, msgId, targetType);
            return ResponseModel.success();
        } else {
            return ResponseModel.errorMsg(messageModel.getMessage());
        }

    }

    @Override
    public ResponseModel pushAllMessage(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO, String msgId, String targetType) throws Exception {
        if (StringUtils.isEmpty(pushConfiguresPO.getOpAppKey())
                || StringUtils.isEmpty(pushConfiguresPO.getOpMasterSecret())
                || StringUtils.isEmpty(pushConfiguresPO.getAppKey())) {
            //如果参数不全 那么走极光
            jPushService.pushAndroid(requestSendBean,pushConfiguresPO,msgId,"6",false);
            return ResponseModel.errorMsg("参数配置不全");
        }
        MessageModel messageModel;
        try {
            messageModel = pushAllMessage(requestSendBean, pushConfiguresPO);
        } catch (Exception e) {
            //发送失败重新尝试一次
            messageModel = pushAllMessage(requestSendBean, pushConfiguresPO);
        }
        //判断成功数是否是0
        if (APPVersionCheckUtil.strToInt(messageModel.getSuccessNum()) == 0){
            return jPushService.pushAndroid(requestSendBean, pushConfiguresPO, msgId, "6", false);
        }
        return pushHistoryService.savePushHistory(requestSendBean, messageModel, msgId, targetType);

    }

    /**
     * 发送单个信息
     *
     * @throws Exception
     */
    private MessageModel pushSignMessage(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO) throws Exception {
        try {
            //使用appKey, masterSecret创建sender对象（每次发送消息都使用这个sender对象）
            Sender sender = new Sender(pushConfiguresPO.getOpAppKey(), pushConfiguresPO.getOpMasterSecret());
            Notification notification = getNotification(requestSendBean.getTitle(), requestSendBean.getContent(), requestSendBean.getExtras()); //创建通知栏消息体

            jPushService.setPassThrougnMsg(requestSendBean, pushConfiguresPO);
            Target target = null; //创建发送对象
            try {
                target = Target.build(requestSendBean.getTokens().get(0));
            } catch (Exception e) {
                e.printStackTrace();
            }
            Result result = sender.unicastNotification(notification, target);  //发送单推消息
            log.info("OppoPush.pushSignMessage result ：{}", result);
            if (result.getReturnCode().getMessage().equals("Success")) {
                return MessageModel.success(requestSendBean.getTokens().size(), requestSendBean.getTokens().size(),"发送成功\n");
            }else {
                return MessageModel.errorMsg(requestSendBean.getTokens().size(), 0, result.getReason()+"\n");
            }
        }catch (Exception e){
            log.error("OppoPush.pushSignMessage Exception.", e);
            return MessageModel.errorMsg(requestSendBean.getTokens().size(), requestSendBean.getTokens().size(), e.getMessage()+"\n");

        }
    }

    /**
     * 发送全部广播
     *
     * @throws Exception
     */

    private MessageModel pushAllMessage(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO) {
        try {
            //使用appKey, masterSecret创建sender对象（每次发送消息都使用这个sender对象）
            Sender sender = new Sender(pushConfiguresPO.getOpAppKey(), pushConfiguresPO.getOpMasterSecret());
            Notification broadNotification = getNotification(requestSendBean.getTitle(), requestSendBean.getContent(), requestSendBean.getExtras());// 创建通知栏消息体
            Result saveResult = sender.saveNotification(broadNotification); // 发送保存消息体请求
            saveResult.getStatusCode(); // 获取http请求状态码
            saveResult.getReturnCode(); // 获取平台返回码
            String messageId = saveResult.getMessageId(); //获取messageId
            Target target = new Target(); // 创建广播目标
            String targetValue = "";
            for (int i = 0; i < requestSendBean.getTokens().size(); i++) {
                targetValue += requestSendBean.getTokens().get(i) + ";";
            }
            if (targetValue != "") {
                targetValue = targetValue.substring(0, targetValue.length() - 1);
            }
            target.setTargetValue(targetValue);
            Result broadResult = sender.broadcastNotification(messageId, target); // 发送广播消息
            log.info("OppoPush.pushAllMessage broadResult {}", broadResult);
            if (broadResult.getReturnCode().getMessage().equals("Success")) {
                List<Result.BroadcastErrorResult> errorList = broadResult.getBroadcastErrorResults();
                jPushService.setPassThrougnMsg(requestSendBean, pushConfiguresPO);
                int failerNum = errorList.size();
                String err="发送成功";
                if (failerNum>0){
                    Set<String> errors = errorList.stream().map(s -> {
                        PushUserVO vo = new PushUserVO();
                        vo.setAppKey(requestSendBean.getAppKey());
                        vo.setManuToken(s.getTargetValue());
                        ResponseModel responseModel = pushUserService.queryByMaunToken(vo);
                        if (responseModel.isSuccess()) {
                            PushUserPO pushUserPO = (PushUserPO) responseModel.getRepData();
                            return pushUserPO.getDeviceId();
                        }
                        return "";
                    }).collect(Collectors.toSet());
                    err = "err:\n"+errors.toString();
                }
                return MessageModel.errorMsg(requestSendBean.getTokens().size(), requestSendBean.getTokens().size() - failerNum, err+"\n");
            } else {
                return MessageModel.errorMsg(requestSendBean.getTokens().size(), 0, broadResult.getReason()+"\n");
            }
        }catch (Exception e){
            log.error("OppoPush.pushAllMessage Exception.", e);
            return MessageModel.errorMsg(requestSendBean.getTokens().size(), 0, e.getMessage()+"\n");
        }

    }
    private Notification getNotification(String title, String content, Map<String, String> map) {
        Notification notification = new Notification();
        /**
         * 以下参数必填项
         */
        notification.setTitle(title);
        notification.setContent(content);
        /**
         * 以下参数非必填项， 如果需要使用可以参考OPPO push服务端api文档进行设置
         */
        //通知栏样式 1. 标准样式  2. 长文本样式  3. 大图样式 【非必填，默认1-标准样式】
        notification.setStyle(1);
        // App开发者自定义消息Id，OPPO推送平台根据此ID做去重处理，对于广播推送相同appMessageId只会保存一次，对于单推相同appMessageId只会推送一次
        notification.setAppMessageId(UUID.randomUUID().toString());
        // 应用接收消息到达回执的回调URL，字数限制200以内，中英文均以一个计算
        notification.setCallBackUrl("http://open-appsp.anji-plus.com/push/pushOppoCallBack");
        // App开发者自定义回执参数，字数限制50以内，中英文均以一个计算
        notification.setCallBackParameter("Oppo回调参数");
        // 点击动作类型0，启动应用；1，打开应用内页（activity的intent action）；2，打开网页；4，打开应用内页（activity）；【非必填，默认值为0】;5,Intent scheme URL
        notification.setClickActionType(1);
        // 应用内页地址【click_action_type为1或4时必填，长度500】
        notification.setClickActionActivity("com.push.demo.internal");
        // 网页地址【click_action_type为2必填，长度500】
        notification.setClickActionUrl("http://www.test.com");
        // 动作参数，打开应用内页或网页时传递给应用或网页【JSON格式，非必填】，字符数不能超过4K，示例：{"key1":"value1","key2":"value2"}
//        notification.setActionParameters("{\"name\":\"value1\",\"content\":\"value2\"}");
        if (map != null) {
            notification.setActionParameters(JSONObject.toJSONString(map));
        } else {

        }
        // 展示类型 (0, “即时”),(1, “定时”)
        notification.setShowTimeType(0);
        // 定时展示开始时间（根据time_zone转换成当地时间），时间的毫秒数
        notification.setShowStartTime(System.currentTimeMillis() + 1000 * 60 * 3);
        // 定时展示结束时间（根据time_zone转换成当地时间），时间的毫秒数
        notification.setShowEndTime(System.currentTimeMillis() + 1000 * 60 * 5);
        // 是否进离线消息,【非必填，默认为True】
        notification.setOffLine(true);
        // 离线消息的存活时间(time_to_live) (单位：秒), 【off_line值为true时，必填，最长3天】
        notification.setOffLineTtl(24 * 3600);
        // 时区，默认值：（GMT+08:00）北京，香港，新加坡
        notification.setTimeZone("GMT+08:00");
        // 0：不限联网方式, 1：仅wifi推送
        notification.setNetworkType(0);
        return notification;

    }


}
